package com.example.music.player

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Intent
import android.os.Binder
import android.os.IBinder
import androidx.core.app.NotificationCompat
import androidx.media3.common.MediaItem
import androidx.media3.common.Player
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.session.MediaSession
import androidx.media3.session.MediaSessionService
import com.example.music.MainActivity
import com.example.music.R
import com.example.music.data.Music
import com.example.music.data.PlaybackState
import com.example.music.data.RepeatMode
import com.example.music.data.ShuffleMode

class MusicPlayerService : Service() {
    
    private var mediaSession: MediaSession? = null
    var exoPlayer: ExoPlayer? = null
        private set
    private val binder = MusicPlayerBinder()
    
    private var currentMusic: Music? = null
    private var musicList: List<Music> = emptyList()
    private var currentIndex: Int = 0
    
    var playbackState: PlaybackState = PlaybackState.STOPPED
        private set
    var repeatMode: RepeatMode = RepeatMode.NONE
        private set
    var shuffleMode: ShuffleMode = ShuffleMode.OFF
        private set
    
    inner class MusicPlayerBinder : Binder() {
        fun getService(): MusicPlayerService = this@MusicPlayerService
    }
    
    override fun onCreate() {
        super.onCreate()
        createNotificationChannel()
        initializePlayer()
    }
    
    // Removed onGetSession as it's not needed for regular Service
    
    private fun initializePlayer() {
        exoPlayer = ExoPlayer.Builder(this).build().apply {
            addListener(object : Player.Listener {
                override fun onPlaybackStateChanged(playbackState: Int) {
                    when (playbackState) {
                        Player.STATE_READY -> {
                            this@MusicPlayerService.playbackState = PlaybackState.PLAYING
                        }
                        Player.STATE_BUFFERING -> {
                            this@MusicPlayerService.playbackState = PlaybackState.BUFFERING
                        }
                        Player.STATE_ENDED -> {
                            this@MusicPlayerService.playbackState = PlaybackState.STOPPED
                            playNext()
                        }
                    }
                }
            })
        }
        
        mediaSession = MediaSession.Builder(this, exoPlayer!!).build()
    }
    
    fun setMusicList(musicList: List<Music>) {
        this.musicList = musicList
    }
    
    fun playMusic(music: Music) {
        currentMusic = music
        currentIndex = musicList.indexOf(music)
        
        val mediaItem = MediaItem.fromUri(music.uri)
        exoPlayer?.setMediaItem(mediaItem)
        exoPlayer?.prepare()
        exoPlayer?.play()
        
        startForegroundService()
    }
    
    fun play() {
        exoPlayer?.play()
        playbackState = PlaybackState.PLAYING
    }
    
    fun pause() {
        exoPlayer?.pause()
        playbackState = PlaybackState.PAUSED
    }
    
    fun stop() {
        exoPlayer?.stop()
        playbackState = PlaybackState.STOPPED
    }
    
    fun playNext() {
        if (musicList.isEmpty()) return
        
        val nextIndex = if (shuffleMode == ShuffleMode.ON) {
            (0 until musicList.size).random()
        } else {
            (currentIndex + 1) % musicList.size
        }
        
        if (nextIndex != currentIndex) {
            currentIndex = nextIndex
            playMusic(musicList[currentIndex])
        }
    }
    
    fun playPrevious() {
        if (musicList.isEmpty()) return
        
        val prevIndex = if (shuffleMode == ShuffleMode.ON) {
            (0 until musicList.size).random()
        } else {
            if (currentIndex == 0) musicList.size - 1 else currentIndex - 1
        }
        
        if (prevIndex != currentIndex) {
            currentIndex = prevIndex
            playMusic(musicList[currentIndex])
        }
    }
    
    fun seekTo(position: Long) {
        exoPlayer?.seekTo(position)
    }
    
    fun getCurrentPosition(): Long {
        return exoPlayer?.currentPosition ?: 0L
    }
    
    fun getDuration(): Long {
        return exoPlayer?.duration ?: 0L
    }
    
    fun setRepeatMode(mode: RepeatMode) {
        repeatMode = mode
        exoPlayer?.repeatMode = when (mode) {
            RepeatMode.NONE -> Player.REPEAT_MODE_OFF
            RepeatMode.ONE -> Player.REPEAT_MODE_ONE
            RepeatMode.ALL -> Player.REPEAT_MODE_ALL
        }
    }
    
    fun setShuffleMode(mode: ShuffleMode) {
        shuffleMode = mode
        exoPlayer?.shuffleModeEnabled = mode == ShuffleMode.ON
    }
    
    private fun startForegroundService() {
        val notification = createNotification()
        startForeground(NOTIFICATION_ID, notification)
    }
    
    private fun createNotificationChannel() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                CHANNEL_ID,
                "Music Player",
                NotificationManager.IMPORTANCE_LOW
            )
            val notificationManager = getSystemService(NotificationManager::class.java)
            notificationManager.createNotificationChannel(channel)
        }
    }
    
    private fun createNotification(): Notification {
        val intent = Intent(this, MainActivity::class.java)
        val pendingIntent = PendingIntent.getActivity(
            this, 0, intent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )
        
        return NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle(currentMusic?.title ?: "Music Player")
            .setContentText(currentMusic?.artist ?: "Unknown Artist")
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .setContentIntent(pendingIntent)
            .setOngoing(true)
            .build()
    }
    
    override fun onDestroy() {
        super.onDestroy()
        exoPlayer?.release()
        mediaSession?.run {
            player.release()
            release()
        }
    }
    
    override fun onBind(intent: Intent?): IBinder {
        return binder
    }
    
    companion object {
        private const val CHANNEL_ID = "music_player_channel"
        private const val NOTIFICATION_ID = 1
    }
}
